class Watcher {
  //vm: vue实例
  //expr: data中数据的name
  //cb: 一旦数据发生了改变, 需要调用cb
  constructor(vm, expr, cb) {
    this.vm = vm
    this.expr = expr
    this.cb = cb

    Dep.target = this
    //需要把expr的旧值存储起来
    this.oldValue = this.getVMValue(vm, expr)
    Dep.target = null
  }

  //对外暴露的一个方法, 用于更新页面
  update() {
    const oldValue = this.oldValue
    const newValue = this.getVMValue(this.vm, this.expr)
    if (oldValue !== newValue) {
      this.cb(newValue, oldValue)
    }
  }

  //获取VM中的数据(兼容复杂对象)
  getVMValue(vm, expr) {
    let data = vm.$data
    expr.split('.').forEach(key => {
      data = data[key]
    })
    return data
  }
}

//订阅发布模式实现
class Dep {
  constructor() {
    this.subs = []
  }

  //添加订阅者
  addSub(watcher) {
    this.subs.push(watcher)
  }

  //通知订阅者
  notify() {
    this.subs.forEach(sub => {
      sub.update()
    })
  }
}